package cn.rkylin.oms.refund.adapter;

import cn.rkylin.core.IDataBaseFactory;
import cn.rkylin.core.utils.SnoGerUtil;
import cn.rkylin.core.utils.StringUtil;
import cn.rkylin.oms.common.base.AbstractAdapterFactory;
import cn.rkylin.oms.common.dto.DBLog;
import cn.rkylin.oms.common.utils.DateUtil;
import cn.rkylin.oms.common.utils.LogUtil;
import cn.rkylin.oms.common.utils.TaobaoEncrypt;
import cn.rkylin.oms.order.domain.OrderStatusMap;
import cn.rkylin.oms.refund.domain.EcRefund;
import cn.rkylin.oms.refund.domain.EcRefundItem;
import cn.rkylin.oms.refund.domain.RefundStatusMap;
import cn.rkylin.oms.refund.domain.taobao.TopPicUrl;
import cn.rkylin.oms.refund.domain.taobao.TopRefund;
import cn.rkylin.oms.refund.domain.taobao.TopRefundMessage;
import cn.rkylin.oms.refund.vo.RdsRefund;
import cn.rkylin.oms.system.shop.domain.Shop;
import cn.rkylin.oms.system.shop.service.IShopService;
import cn.rkylin.oms.system.shop.vo.ShopVO;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.RefundMessagesGetRequest;
import com.taobao.api.response.RefundMessagesGetResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 淘宝退款适配器
 *
 * @author jipengcheng
 * 2017-12-19 李明 重构
 * @version 1.0
 * @created 2017.02.13
 */
@Scope("prototype")
@Service("taoBaoRefundAdapter")
public class TaoBaoRefundAdapter extends RefundAdapter {

    private static final Log logger = LogFactory.getLog(TaoBaoRefundAdapter.class);
    @Autowired
    private LogUtil logUtil;

    @Autowired
    private TaobaoRefundService taobaoRefundService;

    @Autowired
    private TaobaoRefundItemService taobaoRefundItemService;

    @Autowired
    private IShopService shopService;

    /**
     * 淘宝加密类依赖
     */
    TaobaoEncrypt taobaoEncrypt = null;

    /**
     * 测试环境开关
     */
    private Boolean isTest = false;


    /**
     * 数据库访问对象
     */
    @Autowired
    private IDataBaseFactory dao;

    /**
     * 构造函数
     */
    public TaoBaoRefundAdapter() {
    }

    /**
     * 下载退款单
     *
     * @param paramMap
     * @return 1成功，0失败
     */
    @Override
    public int download(String shopId,Map<String, Object> paramMap) throws Exception {
        ShopVO shop = AbstractAdapterFactory.getShop(shopId);

        String dateTimeStart="";
        String dateTimeEnd="";

        if(paramMap.containsKey("refundId") || paramMap.containsKey("buyerNick")) {

        }
        else{
            // 这里重新设置开始时间和结束时间
            dateTimeStart = DateUtil.formatDate(shop.getJobEcRefundLastUpdateTime());
            dateTimeEnd = DateUtil.getCurrentDateStr("yyyy-MM-dd HH:mm:ss");
            paramMap.put("startTime", dateTimeStart);
            paramMap.put("endTime", dateTimeEnd);
        }

        logUtil.info(new DBLog(shopId, "自动下载平台退款单开始",
                "自动下载平台退款单", "shopId="+shopId +";start="+dateTimeStart+";end="+dateTimeEnd));

        // 实例化加密类
        taobaoEncrypt = new TaobaoEncrypt(shop.getAppKey(), shop.getAppSecret(), shop.getSessionKey(), shop.getApiUrl());

        if(taobaoEncrypt == null){
            logUtil.info(new DBLog(shop.getShopAccount(), "获取加密类为null",
                    "自动下载平台退款单", "获取加密类为null"));
            return 0;
        }

        // 如果是按buyerNick查，要把buyerNick加密再去rds里匹配
        if(paramMap.containsKey("buyerNick")){
            try {
                String encryptbuyerNick = taobaoEncrypt.encrypt(paramMap.get("buyerNick").toString(),"simple");
                encryptbuyerNick = StringUtils.substring(encryptbuyerNick,0,StringUtils.length(encryptbuyerNick)-4);
                paramMap.put("buyerNick",encryptbuyerNick);
            } catch(Exception e) {
                throw new Exception("客户ID不存在！");
            }
        }

        saveAllData(shop,paramMap, 0, 10);

        if(paramMap.containsKey("startTime")){
            // 更新最后执行时间
            ShopVO shopUpdate = new ShopVO();
            shopUpdate.setShopId(shopId);
            shopUpdate.setJobEcRefundLastUpdateTime(StringUtil.strToDateTime(dateTimeEnd));
            shopService.update(shopUpdate);
        }

        return 1;
    }

    /**
     * 保存全部数据
     *
     * @param paramMap
     * @param startRow
     * @param count
     * @throws Exception
     */
    private void saveAllData(ShopVO shop,Map<String, Object> paramMap, int startRow, int count) throws Exception {

        List<RdsRefund> list;
        if (startRow == 0) {
            // 获取refund列表
            list = this.getRefundVistor().getTopFundObject(shop,paramMap, 0, count);
        } else {
            list = this.getRefundVistor().getTopFundObject(shop,paramMap, startRow, count);
        }

        saveRefundData(shop,list);

        if (list.size() == count) {
            //递归调用
            saveAllData(shop,paramMap, startRow + count, count);
        }

    }

    /**
     * 保存退款数据
     *
     * @param list
     * @throws Exception
     */
    private void saveRefundData(ShopVO shop,List<RdsRefund> list) throws Exception {
        for (RdsRefund rdsRefund : list) {
            try {
                // 保存淘宝退款
                saveTopRefund(rdsRefund);

                // 保存淘宝退款mesage、url
                // 这个可以暂时屏蔽
                if(1==2) {
                    saveTopRefundMessage(shop,Long.valueOf(rdsRefund.getRefund_id()));
                }

                // 保存平台退款
                saveEcRefundData(shop,rdsRefund);
            } catch (Exception ex) {
                logUtil.error(new DBLog(shop.getShopAccount(), "单条下载退款单异常",
                        "自动下载平台退款单", ex.getMessage()), ex);
                continue;
            }
        }
    }

    /**
     * 保存淘宝退款数据
     *
     * @param rdsRefund
     * @return
     */
    private void saveTopRefund(RdsRefund rdsRefund) {

        //日期格式化
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            TopRefund topRefund = new TopRefund();
            topRefund.setUpdateTime(date);
            topRefund.setAddress(rdsRefund.getAddress());
            //topRefund.set rdsRefund.getAdvance_status();
            topRefund.setAlipayNo(rdsRefund.getAlipay_no());
            topRefund.setAttribute(rdsRefund.getAttribute());
            topRefund.setBuyerNick(rdsRefund.getBuyer_nick());
            topRefund.setCompanyName(rdsRefund.getCompany_name());
            topRefund.setCreated(sdf.parse(rdsRefund.getCreated()));
            topRefund.setCsStatus(rdsRefund.getCs_status() != null ? Integer.valueOf(rdsRefund.getCs_status()) : null);
            topRefund.setDescc(rdsRefund.getDesc());
            if (rdsRefund.getGood_return_time() != null) {
                topRefund.setGoodReturnTime(sdf.parse(rdsRefund.getGood_return_time()));
            }
            topRefund.setGoodStatus(rdsRefund.getGood_status());
            topRefund.setHasGoodReturn("true".equals(rdsRefund.getHas_good_return()) ? 1 : 0);
            topRefund.setModified(sdf.parse(rdsRefund.getModified()));
            topRefund.setNum(rdsRefund.getNum() != null ? Integer.valueOf(rdsRefund.getNum()) : null);
            topRefund.setNumIid(rdsRefund.getNum_iid() != null ? Long.valueOf(rdsRefund.getNum_iid()) : null);
            topRefund.setOid(rdsRefund.getOid() != null ? Long.valueOf(rdsRefund.getOid()) : null);
            topRefund.setOperationContraint(rdsRefund.getOperation_contraint());
            topRefund.setOrderStatus(rdsRefund.getOrder_status());
            topRefund.setOuterId(rdsRefund.getOuter_id());
            topRefund.setPayment(rdsRefund.getPayment() != null ? new BigDecimal(rdsRefund.getPayment()) : null);
            topRefund.setPrice(rdsRefund.getPrice() != null ? new BigDecimal(rdsRefund.getPrice()) : null);
            topRefund.setReason(rdsRefund.getReason());
            topRefund.setRefundFee(rdsRefund.getRefund_fee() != null ? new BigDecimal(rdsRefund.getRefund_fee()) : null);
            topRefund.setRefundId(rdsRefund.getRefund_id() != null ? Long.valueOf(rdsRefund.getRefund_id()) : null);
            topRefund.setRefundPhase(rdsRefund.getRefund_phase());
            topRefund.setRefundVersion(rdsRefund.getRefund_version() != null ? Long.valueOf(rdsRefund.getRefund_version()) : null);
            topRefund.setSellerNick(rdsRefund.getSeller_nick());
            topRefund.setShippingType(rdsRefund.getShipping_type());
            topRefund.setSid(rdsRefund.getSid());
            topRefund.setSku(rdsRefund.getSku());
            topRefund.setStatus(rdsRefund.getStatus());
            topRefund.setTid(rdsRefund.getTid() != null ? Long.valueOf(rdsRefund.getTid()) : null);
            topRefund.setTitle(rdsRefund.getTitle());
            topRefund.setTotalFee(rdsRefund.getTotal_fee() != null ? new BigDecimal(rdsRefund.getTotal_fee()) : null);
            if (rdsRefund.getRefund_remind_timeout() != null) {
                topRefund.setRemindType(new Long((long) rdsRefund.getRefund_remind_timeout().getRemind_type()));
                topRefund.setExistTimeout("true".equals(rdsRefund.getRefund_remind_timeout().getExist_timeout()) ? true : false);
                topRefund.setTimeout(rdsRefund.getRefund_remind_timeout().getTimeout());
            }

            // 检查退款单是否存在
            TopRefund topRefundExists = (TopRefund) dao.find("selectByRefundIdTopRefund", rdsRefund.getRefund_id());
            if (topRefundExists == null) {
                // 添加数据
                topRefund.setTopRefundId(SnoGerUtil.getUUID());
                dao.insert("insertSelectiveTopRefund", topRefund);
            } else {
                // 更新数据
                topRefund.setTopRefundId(topRefundExists.getTopRefundId());
                dao.update("updateByPrimaryKeySelectiveTopRefund", topRefund);
            }
        } catch (Exception ex) {
            logUtil.error(new DBLog(rdsRefund.getRefund_id(), "saveTopRefund异常",
                    "自动下载平台退款单", rdsRefund.getRefund_id()+"出错:" + ex.getMessage()), ex);
        }
    }

    /**
     * 退款留言/凭证列表
     *
     * @param refundId 退款单号
     * @return 1成功，0失败
     */
    private void saveTopRefundMessage(ShopVO shop,long refundId) throws Exception {

        // 根据refundId 获取相关退款单
        TopRefund modelTopRefund = (TopRefund) dao.find("selectByRefundIdTopRefund", String.valueOf(refundId));

        // taobao.refund.messages.get
        TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
        RefundMessagesGetRequest req = new RefundMessagesGetRequest();
        req.setFields("id, refund_id, owner_id, owner_nick, owner_role, content, pic_urls,created, message_type");
        req.setRefundId(refundId);
        req.setPageNo(1L);
        req.setPageSize(20L);
        req.setRefundPhase(modelTopRefund.getRefundPhase());

        RefundMessagesGetResponse rsp = client.execute(req, shop.getSessionKey());
        if (rsp.isSuccess() == false) {
            return;
        }
        if (rsp.getRefundMessages() == null || rsp.getRefundMessages().size() < 1) {
            return;
        }

        for (com.taobao.api.domain.RefundMessage refundMessage : rsp.getRefundMessages()) {

            TopRefundMessage topRefundMessage = new TopRefundMessage();
            org.apache.commons.beanutils.BeanUtils.copyProperties(topRefundMessage, refundMessage);

            // 检查 退款留言/凭证列表 是否存在
            TopRefundMessage modelTopRefundMessage = (TopRefundMessage) dao.find("selectByPrimaryKeyTopRefundMessage",
                    refundMessage.getId());
            if (modelTopRefundMessage == null) {
                // 添加数据
                topRefundMessage.setTopRefundMessageId(SnoGerUtil.getUUID());
                dao.insert("insertSelectiveTopRefundMessage", topRefundMessage);
            } else {
                // 更新数据
                topRefundMessage.setTopRefundMessageId(modelTopRefundMessage.getTopRefundMessageId().toString());
                dao.update("updateByPrimaryKeySelectiveTopRefundMessage", topRefundMessage);
            }

            if (refundMessage.getPicUrls() != null && refundMessage.getPicUrls().size() > 0) {
                for (com.taobao.api.domain.PicUrl picUrl : refundMessage.getPicUrls()) {

                    TopPicUrl topPicUrl = new TopPicUrl();
                    topPicUrl.setId(topRefundMessage.getId());
                    org.apache.commons.beanutils.BeanUtils.copyProperties(topPicUrl, picUrl);

                    TopPicUrl modelTopPicUrl = (TopPicUrl) dao.find("selectByUrlTopPicUrl", topPicUrl.getUrl());

                    if (modelTopPicUrl == null) {
                        topPicUrl.setTopRefundPicUrlId(SnoGerUtil.getUUID());
                        // 添加数据
                        dao.insert("insertSelectiveTopPicUrl", topPicUrl);
                    } else {
                        // 更新数据
                        topPicUrl.setTopRefundPicUrlId(modelTopPicUrl.getTopRefundPicUrlId());
                        dao.update("updateByPrimaryKeySelectiveTopPicUrl", topPicUrl);
                    }
                }
            }
        }
    }

    /**
     * 解析订单数据并且保存到数据库
     *
     * @param rdsRefund
     * @return
     */
    private void saveEcRefundData(ShopVO shop,RdsRefund rdsRefund) {
        try {
            String ecRefundId = saveEcRefund(rdsRefund, shop);
            saveEcRefundItem(ecRefundId, rdsRefund, shop);
        } catch (Exception ex) {
            logUtil.error(new DBLog(rdsRefund.getRefund_id(), "saveEcRefundData异常",
                    "自动下载平台退款单", rdsRefund.getRefund_id()+"出错:" + ex.getMessage()), ex);
        }
    }

    /**
     * 保存EcRefund
     *
     * @param rdsRefund
     * @param shopVO
     * @return
     * @throws Exception
     */
    private String saveEcRefund(RdsRefund rdsRefund, Shop shopVO) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        EcRefund ecRefund = new EcRefund();

        ecRefund.setRefundDesc(rdsRefund.getDesc());
        ecRefund.setErrDesc("");
        ecRefund.setSplitStatus("n");
        ecRefund.setPrjId(shopVO.getPrjId());
        ecRefund.setPrjName(shopVO.getPrjName());
        ecRefund.setShopId(shopVO.getShopId());
        ecRefund.setShopName(shopVO.getShopName());
        ecRefund.setEcRefundCode(rdsRefund.getRefund_id());// rdsRefund.getRefund_id()
        ecRefund.setEcTradeCode(rdsRefund.getTid());// rdsRefund.getOid()
        ecRefund.setShopAccount(shopVO.getShopAccount());
        ecRefund.setBuyerNick(taobaoEncrypt.decript(rdsRefund.getBuyer_nick(), "simple"));// rdsRefund.getBuyer_nick()
        ecRefund.setRefundFee(rdsRefund.getRefund_fee() != null ? new BigDecimal(rdsRefund.getRefund_fee()) : null);// rdsRefund.getRefund_fee()
        if(this.isTest){
            ecRefund.setRefundStatus("EC_WAIT_SELLER_AGREE");
        }else {
            ecRefund.setRefundStatus(RefundStatusMap.statusMap.get(rdsRefund.getStatus()));// rdsRefund.getStatus()
        }
        ecRefund.setRefundReason(rdsRefund.getReason());// rdsRefund.getReason()
        ecRefund.setEcTradeStus(OrderStatusMap.statusMap.get(rdsRefund.getOrder_status()));// rdsRefund.getOrder_status()
        ecRefund.setHasGoodReturn("true".equals(rdsRefund.getHas_good_return()) ? "y" : "n");// rdsRefund.getHas_good_return()
        ecRefund.setGoodStus(rdsRefund.getGood_status());// rdsRefund.getGood_status()
        ecRefund.setLgstName(rdsRefund.getCompany_name());
        ecRefund.setLgstNo(rdsRefund.getSid());
        ecRefund.setRefundAddress(rdsRefund.getAddress());// rdsRefund.getAddress()
        ecRefund.setShopType(shopVO.getShopType());
        ecRefund.setRefundCreateTime(sdf.parse(rdsRefund.getCreated()));// rdsRefund.getCreated()
        if (rdsRefund.getRefund_remind_timeout() != null) {
            ecRefund.setRefundTimeout(rdsRefund.getRefund_remind_timeout().getTimeout());
        }
        if ("CLOSED".equals(rdsRefund.getStatus())) {
            ecRefund.setCloseTime(sdf.parse(rdsRefund.getModified()));
        }
        if ("SUCCESS".equals(rdsRefund.getStatus())) {
            ecRefund.setRefundTime(sdf.parse(rdsRefund.getModified()));
        }

        ecRefund.setRefundPhase(rdsRefund.getRefund_phase());

        EcRefund ecRefundExists = taobaoRefundService.selectEcRefundByRefundId(rdsRefund.getRefund_id());
        if (ecRefundExists == null) {
            ecRefund.setEcRefundId(SnoGerUtil.getUUID());
            taobaoRefundService.insert("insertSelectiveEcRefund", ecRefund);
        } else {
            ecRefund.setEcRefundId(ecRefundExists.getEcRefundId());
            taobaoRefundService.update("updateByPrimaryKeySelectiveEcRefund", ecRefund);
        }

        return ecRefund.getEcRefundId();
    }

    /**
     * 保存EcRefundItem
     *
     * @param ecRefundId
     * @param rdsRefund
     * @param shopVO
     * @return
     * @throws Exception
     */
    private String saveEcRefundItem(String ecRefundId, RdsRefund rdsRefund, Shop shopVO) throws Exception {

        EcRefundItem ecRefundItem = new EcRefundItem();
        ecRefundItem.setEcItemCode(rdsRefund.getNum_iid());
        ecRefundItem.setEcItemName(rdsRefund.getTitle());
        ecRefundItem.setEcSkuCode(getEcSkuCode(rdsRefund.getSku()));
        ecRefundItem.setEcSkuName(rdsRefund.getSku());
        ecRefundItem.setEcOid(rdsRefund.getOid());
        ecRefundItem.setQty(rdsRefund.getNum() != null ? Integer.valueOf(rdsRefund.getNum()) : null);
        // ecRefundItem.setItemStatus(itemStatus);
        ecRefundItem.setRefundFee(rdsRefund.getRefund_fee() != null ? new BigDecimal(rdsRefund.getRefund_fee()) : null);
        ecRefundItem.setSplitShopId(shopVO.getShopId());
        ecRefundItem.setSplitShopName(shopVO.getShopName());

        // 根据ecRefundId判断
        EcRefundItem ecRefunditemExists = taobaoRefundItemService.selectEcRefundItemByRefundId(ecRefundId);

        if (ecRefunditemExists == null) {
            ecRefundItem.setEcRefundItemId(SnoGerUtil.getUUID());
            ecRefundItem.setEcRefundId(ecRefundId);
            taobaoRefundItemService.insert("insertSelectiveEcRefundItem", ecRefundItem);
        } else {
            ecRefundItem.setEcRefundItemId(ecRefunditemExists.getEcRefundItemId());
            taobaoRefundItemService.update("updateByPrimaryKeySelectiveEcRefundItem", ecRefundItem);
        }

        return ecRefundItem.getEcRefundItemId();
    }

    /**
     * 解析ecSkuCode
     * 66096479280|颜色分类:黑色;鞋码:37
     * @param sku
     * @return
     */
    private String getEcSkuCode(String sku) {
        if (StringUtils.isEmpty(sku)) {
            return "0";
        }
        String ecSkuCode = "0";
        try {
            String[] skuArray = sku.split("\\|");
            ecSkuCode = skuArray[0];
        } catch (Exception ex) {
            logUtil.error(new DBLog("", "getEcSkuCode异常",
                    "自动下载平台退款单", "解析EcSkuCode" + sku + "出错:" + ex.getMessage()), ex);
        }
        return ecSkuCode;
    }

}
